﻿#ifndef MATRIXCOMPUTE_H
#define MATRIXCOMPUTE_H

/**
 * @brief damul 实矩阵相乘, 计算矩阵A（m*n）和B（n*k）的乘积，结果保存在C（m*k）中
 * @param matA 长度为m*n的数组
 * @param matB 长度为n*k的数组
 * @param m
 * @param n
 * @param k
 * @param matC 长度为m*k的数组，存放结果
 */
void damul(const double matA[], const double matB[], int m, int n, int k, double matC[]);

/**
 * @brief ATdotB  计算矩阵A（m*n）的转置矩阵AT（n*m）和B（m*k）的乘积，结果保存在C（n*k）中
 * @param matA  长度为m*n的数组
 * @param matB  长度为m*k的数组
 * @param m
 * @param n
 * @param k
 * @param matC  长度为n*k的数组，存放结果
 */
void ATdotB(const double matA[], const double matB[], int m, int n, int k, double matC[]);

/**
 * @brief AdotBT  计算矩阵A（m*n）和B（k*n）的转置矩阵BT（n*k）的乘积，结果保存在C（m*k）中
 * @param matA  长度为m*n的数组
 * @param b  长度为k*n的数组
 * @param m
 * @param n
 * @param k
 * @param matC  长度为m*k的数组，存放结果
 */
void AdotBT(const double matA[], const double matB[], int m, int n, int k, double matC[]);

/**
 * @brief dcinv   实矩阵求逆, 全选主元高斯-约当法
 * @param matA  长度为n*n的数组, n*n矩阵
 * @param n  矩阵的维数
 * @param  permRow 辅助数据，长度为 n, 记录行交换结果
 * @param  permCol 辅助数据，长度为 n，记录列交换结果
 * @return
 */
int dcinv(double matA[], int n, int permRow[], int permCol[]);


/**
 * @brief desgj   对称正定矩阵求逆
 * @param a  长度为n*n的数组, n*n矩阵
 * @param n  矩阵的维数
 * @param b  辅助数组，长度为 n， 存放一些临时计算结果
 * @return  > 0 表示成功， < 0 说明出现问题
 */
int desgj(double matA[], int n, double b[]);

/**
 * @brief dftrn  托伯利兹(Toeplitz)矩阵求逆的特兰持(Trench)方法
 * @param t      长度为n的数组,存放n阶T型矩阵中的上三角元素t0,t1,t2...tn-1
 * @param tt     长度为n的数组,从tt[1]开始依次存放tt[1]...tt[n-1]
 * @param n      矩阵的阶数
 * @param b      长度为n*n的数组，返回时存放逆矩阵
 * @return
 */
int dftrn(double t[], double tt[], int n, double b[]);

/**
 * @brief dhdet  求矩阵的行列式值, 采用全选主元高斯消去法
 * @param matA      长度为n*n的数组, matA 的内容会被破坏
 * @param n      矩阵的阶数
 * @return
 */
double dhdet(double matA[], int n);

/**
 * @brief dicll   对称正定矩阵的乔里斯基(Cholesky)分解与行列式求值
 * @param matA    长度为n*n的数组，存放正定矩阵，返回时下三角部分存放分解后的下三角矩阵L,其余元素为0
 * @param n   正定矩阵的阶数
 * @param det  指向双精度实型变量的指针，返回时该指针指向的变量存放行列式的值
 * @return   返回值小于0表示程序工作失败，还输出"fail";  返回值大于0表示正常返回
 */
int dicll(double matA[], int n, double  *det);

/**
 * @brief djlu  矩阵的三角分解(LU), 其中下三角阵L的主对角元素为1。
 * @param matA  长度为N*N的矩阵，返回时为L+U-I
 * @param n     矩阵的阶数
 * @param matL  返回下三角矩阵
 * @param matU  返回上三角矩阵
 * @return
 */
int djlu(double matA[], int n, double matL[], double matU[]);

/**
 * @brief dkqr  实数矩阵的QR分解法, 用Householder变换对一般m*n阶的实数矩阵进行QR分解
 * @param matA  长度为m*n的一维数组,返回时其左上三角部分存放上三角矩阵R
 * @param m     矩阵的行数
 * @param n     矩阵的列数
 * @param matQ  长度为m*m的矩阵，返回时存放正交矩阵Q
 * @return
 */
int dkqr(double matA[], int m, int n, double matQ[]);

/**
 * @brief dginv  奇异值分解法求广义逆, 调用函数：dluav()
 * @param matA   长度为m*n的数组，返回时其对角线依次给出奇异值，其余元素为0
 * @param m   矩阵的行数
 * @param n   矩阵的列数
 * @param aa  长度为n*m的数组，返回式存放A的广义逆
 * @param eps  精度要求
 * @param matU  长度为m*m的数组，返回时存放奇异值分解的左奇异量U
 * @param matV  长度为n*n的数组，返回时存放奇异值分解的左奇异量V
 * @return  本函数返回值小于0表示在奇异值分解过程, 中迭代值超过了60次还未满足精度要求. 返回值大于0表示正常返回。
 */
int dginv(double matA[], int m, int n, double aa[], double eps, double matU[], double matV[]);

/**
 * @brief dluav  实数矩阵的奇异值分解, 用Householder变换及变形QR算法. 调用函数：dluav(),ppp(),sss()
 * @param matA   长度为m*n的数组，返回时其对角线依次给出奇异值，其余元素为0
 * @param m      矩阵的行数
 * @param n      矩阵的列数
 * @param matU   长度为m*m的数组，返回时存放奇异值分解的左奇异量U
 * @param matV   长度为n*n的数组，返回时存放奇异值分解的左奇异量V
 * @param eps  精度要求
 * @return
 */
int dluav(double matA[], int m, int n, double matU[], double matV[], double eps);



/**
 * @brief dbcmul  复数矩阵相乘,计算矩阵A（m*n）和B（n*k）的乘积，结果保存在C（m*k）中
 * @param matAR   长度为m*n的数组,存放A的实部
 * @param matAI   长度为m*n的数组,存放A的虚部
 * @param matBR   长度为n*k的数组,存放B的实部
 * @param matBI   长度为n*k的数组,存放B的虚部
 * @param m
 * @param n
 * @param k
 * @param matCR   长度为m*k的数组，存放结果C的实部
 * @param matCI   长度为m*k的数组，存放结果C的虚部
 */
void dbcmul(const double matAR[], const double matAI[], const double matBR[], const double matBI[], int m, int n, int k, double matCR[], double matCI[]);

/**
 * @brief ddcinv  复数矩阵求逆
 * @param matAR   长度为n*n的数组, n*n矩阵的实部
 * @param matAI   长度为n*n的数组, n*n矩阵的虚部
 * @param n       矩阵的维数
 * @return
 */
int ddcinv(double matAR[], double matAI[], int n);
#endif // MATRIXCOMPUTE_H
